﻿#define _CRT_SECURE_NO_WARNINGS 1

//运算符重载

//C++规定类类型对象使⽤运算符时，必须转换成调⽤对应运算符重载
//运算符重载是具有特殊名字的函数，他的名字是由operator和后⾯要定义的运算符共同构成,它也具有其返回类型和参数列表以及函数体。
//重载运算符函数的参数个数和该运算符作⽤的运算对象数量⼀样多
//如果⼀个重载运算符函数是成员函数，则它的第⼀个运算对象默认传给隐式的this指针，因此运算符重载作为成员函数时，参数⽐运算对象少⼀个。
//运算符重载以后，其优先级和结合性与对应的内置类型运算符保持⼀致
//不能通过连接语法中没有的符号来创建新的操作符
//.* :: sizeof ?: . 注意以上5个运算符不能重载
//重载操作符⾄少有⼀个类类型参数

#include <iostream>
using namespace std;


//例如重载==判断两个日期类时间是否相等

//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void Print()
//	{
//		cout << _year << "-" << _month << "-" << _day << endl;
//	}
//
////private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//
////当然我们在重载运算符时也要判断该运算有无意义 比如两个日期相加没有意义 但两个日期相减就有意义
//bool operator==(const Date& x1, const Date& x2)
//{
//	return x1._year == x2._year
//		&& x1._month == x2._month
//		&& x1._day == x2._day;
//}
//
//int main()
//{
//	Date d1(2025, 1, 18);
//	Date d2(2025, 1, 18);
//	Date d3(2024, 12, 23);
//	bool ret1 = d1 == d2;
//	bool ret2 = d1 == d3;
//	cout << ret1 << endl << ret2 << endl;
//	return 0;
//}


class Date  //日期类不需要显式地写析构和拷贝构造
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

	bool operator==(const Date& d)  //如果想要将其写成类里的成员函数 则参数数量要少一个，因为前面还有一个this指针的隐式参数
	{
		return this->_year == d._year
			&& this->_month == d._month
			&& this->_day == d._day;
		//那么写在成员函数里有什么好处呢,比如我们想重载+=这个运算符
		//那么d本身改变 我们希望返回他自己 这时就可以return *this;
	}

private:
	int _year;
	int _month;
	int _day;
};

// d1 - d2  计算两个日期间差了多少天
//int operator-(const Date& x1, const Date& x2)
//{
//
//	return 0;
//}
//
// d1 - 100 计算某个天数以前是什么时候
//Date operator-(const Date& x1, int day)
//{
//	Date ret;
//
//	return ret;
//}

//int main()
//{
//	Date d1(2024, 11, 14);
//	Date d2(2024, 11, 11);
//	
//	//bool ret0 = d1.operator==(d2);
//	bool ret1 = d1 == d2;
//	cout << ret1 << endl;
//	return 0;
//}



//来看以下.*运算符
class A
{
public:
	void func1()
	{
		cout << "A::func()" << endl;
	}
};

typedef void(A::* PF1)(); //成员函数指针类型
typedef void(*PF2)();	//函数指针类型

void func2()
{
	cout << "func2()" << endl;
}

int main()
{
	//C++规定成员函数要加&才能取到函数指针
	PF1 pf1 = &A::func1;
	A obj;
	(obj.*pf1)();  //使用.*

	PF2 pf2 = func2;
	(*pf2)();
	return 0;
}